
Free Information Xchange '98 presents:

Need For Speed 3: Hot Pursuit - CD crack by Static Vengeance - Oct 7th, 1998

	Need for Speed 3: Hot Pursuit (NFS3) is an awesome new racing game.  The graphics on a 3Dfx based
card are fantasic and game speed is great.  You can play a multi player game on-line or in split screen
mode.  You have the option of racing alone or in the "Hot Pursuit" mode in which you're chased by cops.
You can choose which type of car you want to drive.  Then you also have the option of downloading new cars
off the web and eventually new tracks.  Electronic Arts has put out a patch that will automaticly check
EA's ftp site and check if there is newer version of NFS3.  If there is, the "Network Play System" will 
download and install the latest patch/update for you.
	With such a great game there is little wonder that there is some type of copy protection included.  
The first thing that needs to be done is to install the game.  Check out what has been installed versus what
files are still on the CD.  You will see that not all the files used are copied from NFS3 CD.  In fact there
are a lot of audio files and the movies files that are not copied.  Load up the file install.win with note
pad and you'll see path directories used by the game.  Any path that has your CD rom drive letter in it means
those files are stored on the CD.
	One option is to copy the directories (with all thier files) to your hard drive, then edit install.win
to point to the new locations.  This will work except it takes over 500 megs of hard drive space to do.  Then
there is still the CD check.  This will be our first objective, remove the CD check.
	Using W32Dasm, disassemble nfs3.exe and look for useful data string references.  Eventually you come
acrros "C:NFS3.EXE" and "A:\"  Double click on the "A:\" and you'll be in the middle of this routine:

* Referenced by a CALL at Addresses:
|:004B657B   , :004B65DC                                    <-- Called twice
|
:004F9820 51                      push ecx
:004F9821 52                      push edx
:004F9822 56                      push esi
:004F9823 57                      push edi
:004F9824 83EC04                  sub esp, 00000004
:004F9827 89C2                    mov edx, eax

* Possible StringData Ref from Data Obj ->"A:\"                 <-- Commonly used in CD checks
                                  |
:004F9829 BE24E95400              mov esi, 0054E924
:004F982E 89E7                    mov edi, esp
:004F9830 57                      push edi

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004F9847(C)
|
:004F9831 8A06                    mov al, byte ptr [esi]
:004F9833 8807                    mov byte ptr [edi], al
:004F9835 3C00                    cmp al, 00
:004F9837 7410                    je 004F9849
:004F9839 8A4601                  mov al, byte ptr [esi+01]
:004F983C 83C602                  add esi, 00000002
:004F983F 884701                  mov byte ptr [edi+01], al
:004F9842 83C702                  add edi, 00000002
:004F9845 3C00                    cmp al, 00
:004F9847 75E8                    jne 004F9831

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004F9837(C)
|
:004F9849 5F                      pop edi
:004F984A 001424                  add byte ptr [esp], dl
:004F984D 89E0                    mov eax, esp
:004F984F 50                      push eax

* Reference To: KERNEL32.GetDriveTypeA, Ord:0025h                  <-- Commonly used in CD check routines
                                  |
:004F9850 2EFF1518555300          Call dword ptr cs:[00535518]
:004F9857 83F805                  cmp eax, 00000005                <-- 05 is the value of a CD rom drive
:004F985A 7515                    jne 004F9871
:004F985C B801000000              mov eax, 00000001                <-- Load eax with 01 for finding CD drive
:004F9861 83C404                  add esp, 00000004
:004F9864 5F                      pop edi
:004F9865 5E                      pop esi
:004F9866 5A                      pop edx
:004F9867 59                      pop ecx
:004F9868 8D8000000000            lea eax, dword ptr [eax+00000000]
:004F986E 8BD2                    mov edx, edx
:004F9870 C3                      ret

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004F985A(C)
|
:004F9871 31C0                    xor eax, eax                    <-- Eax = zero for no CD rom drive in system
:004F9873 83C404                  add esp, 00000004
:004F9876 5F                      pop edi
:004F9877 5E                      pop esi
:004F9878 5A                      pop edx
:004F9879 59                      pop ecx
:004F987A C3                      ret

	That routine was somewhat short, so now we'll look at the calling routine:

* Referenced by a CALL at Address:
|:004A4227                                               <-- Called once
|
:004B6540 53                      push ebx
:004B6541 51                      push ecx
:004B6542 52                      push edx
:004B6543 56                      push esi
:004B6544 57                      push edi
:004B6545 55                      push ebp
:004B6546 89E5                    mov ebp, esp
:004B6548 81EC3C010000            sub esp, 0000013C
:004B654E 8D7DF4                  lea edi, dword ptr [ebp-0C]
:004B6551 BB00010000              mov ebx, 00000100

* Possible StringData Ref from Code Obj ->"C:NFS3.EXE"        <-- File to search for
                                  |
:004B6556 BEA8584B00              mov esi, 004B58A8

* Possible StringData Ref from Data Obj ->"install.win"
                                  |
:004B655B BA340E5400              mov edx, 00540E34
:004B6560 8D85C4FEFFFF            lea eax, dword ptr [ebp+FFFFFEC4]
:004B6566 A5                      movsd
:004B6567 A5                      movsd
:004B6568 66A5                    movsw
:004B656A A4                      movsb
:004B656B E830320400              call 004F97A0
:004B6570 8D85C4FEFFFF            lea eax, dword ptr [ebp+FFFFFEC4]
:004B6576 E885320400              call 004F9800
:004B657B E8A0320400              call 004F9820              <-- Check for a CD rom drive on system
:004B6580 85C0                    test eax, eax
:004B6582 7430                    je 004B65B4
:004B6584 B906000000              mov ecx, 00000006
:004B6589 8D7DDC                  lea edi, dword ptr [ebp-24]
:004B658C BEB4584B00              mov esi, 004B58B4
:004B6591 6A30                    push 00000030
:004B6593 A150AA7A00              mov eax, dword ptr [007AAA50]
:004B6598 F3                      repz
:004B6599 A5                      movsd

* Possible StringData Ref from Data Obj ->"Need For Speed 3"
                                  |
:004B659A 68400E5400              push 00540E40
:004B659F 8B5485DC                mov edx, dword ptr [ebp+4*eax-24]
:004B65A3 52                      push edx
:004B65A4 6A00                    push 00000000

* Reference To: USER32.MessageBoxA, Ord:001Fh
                                  |
:004B65A6 2EFF1564575300          Call dword ptr cs:[00535764]
:004B65AD 31C0                    xor eax, eax
:004B65AF E890990200              call 004DFF44

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004B6582(C)
|
:004B65B4 E807FFFFFF              call 004B64C0
:004B65B9 85C0                    test eax, eax
:004B65BB 755A                    jne 004B6617
:004B65BD 31D2                    xor edx, edx
:004B65BF EB19                    jmp 004B65DA

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004B65E3(C)
|
:004B65C1 88D0                    mov al, dl
:004B65C3 0441                    add al, 41
:004B65C5 8845F4                  mov byte ptr [ebp-0C], al
:004B65C8 8D45F4                  lea eax, dword ptr [ebp-0C]
:004B65CB E8C0A70300              call 004F0D90
:004B65D0 85C0                    test eax, eax
:004B65D2 7543                    jne 004B6617

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004B65E5(U)
|
:004B65D4 42                      inc edx
:004B65D5 83FA1A                  cmp edx, 0000001A
:004B65D8 7D0D                    jge 004B65E7

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004B65BF(U)
|
:004B65DA 89D0                    mov eax, edx
:004B65DC E83F320400              call 004F9820               <-- Check again for a CD rom drive
:004B65E1 85C0                    test eax, eax
:004B65E3 75DC                    jne 004B65C1
:004B65E5 EBED                    jmp 004B65D4

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004B65D8(C)
|
:004B65E7 B906000000              mov ecx, 00000006
:004B65EC 8D7DC4                  lea edi, dword ptr [ebp-3C]
:004B65EF BECC584B00              mov esi, 004B58CC
:004B65F4 6A30                    push 00000030
:004B65F6 A150AA7A00              mov eax, dword ptr [007AAA50]
:004B65FB F3                      repz
:004B65FC A5                      movsd

* Possible StringData Ref from Data Obj ->"Need For Speed 3"
                                  |
:004B65FD 68400E5400              push 00540E40
:004B6602 8B4C85C4                mov ecx, dword ptr [ebp+4*eax-3C]
:004B6606 51                      push ecx
:004B6607 6A00                    push 00000000

* Reference To: USER32.MessageBoxA, Ord:001Fh
                                  |
:004B6609 2EFF1564575300          Call dword ptr cs:[00535764]
:004B6610 31C0                    xor eax, eax
:004B6612 E82D990200              call 004DFF44

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:004B65BB(C), :004B65D2(C)
|
:004B6617 89EC                    mov esp, ebp
:004B6619 5D                      pop ebp
:004B661A 5F                      pop edi
:004B661B 5E                      pop esi
:004B661C 5A                      pop edx
:004B661D 59                      pop ecx
:004B661E 5B                      pop ebx
:004B661F C3                      ret

	That was the heart of the CD check.  It was only called once so let's check out the code
that surounds the call to the CD check:

  -- Program code --
:004A421E 7507                    jne 004A4227
:004A4220 31C0                    xor eax, eax
:004A4222 E8491E0100              call 004B6070

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004A421E(C)
|
:004A4227 E814230100              call 004B6540                 <-- Check for the CD
:004A422C E81FF6FFFF              call 004A3850
:004A4231 F6059A5E560020          test byte ptr [00565E9A], 20
:004A4238 7465                    je 004A429F
:004A423A B801000000              mov eax, 00000001
  -- Continuing program code --

	Well, there is no type of check for any returned result so overwriting this call will kill the
CD check.  That was simple enough, now on to the harder stuff.
	Filling up 500+ megs of hard drive space just isn't reasonable.  Time to start freeing up space.
First thing we don't need is to see the movies time and time again.  Killing the intro movies is easy by
searching for titleav.mad you'll find this routine:


:00496733 A1A4317A00              mov eax, dword ptr [007A31A4]
:00496738 2B05B4585600            sub eax, dword ptr [005658B4]
:0049673E 3D00140000              cmp eax, 00001400             <-- Time for the "atract" mode
:00496743 7D08                    jge 0049674D                  <-- Do intro / demo movies
:00496745 31C0                    xor eax, eax
:00496747 5D                      pop ebp
:00496748 5E                      pop esi
:00496749 5A                      pop edx
:0049674A 59                      pop ecx
:0049674B 5B                      pop ebx
:0049674C C3                      ret

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00496743(C)
|                                                                   <-- Get's here by conditional jump
:0049674D E87EA3F7FF              call 00410AD0
:00496752 A1B8585600              mov eax, dword ptr [005658B8]
:00496757 83F803                  cmp eax, 00000003
:0049675A 7726                    ja 00496782
:0049675C FF2485B0664900          jmp dword ptr [4*eax+004966B0]

* Possible StringData Ref from Data Obj ->"titleav.mad"             <-- The title movie
                                  |
:00496763 B878CF5300              mov eax, 0053CF78
:00496768 EB13                    jmp 0049677D

* Possible StringData Ref from Data Obj ->"demoav1.mad"
                                  |
:0049676A B884CF5300              mov eax, 0053CF84
:0049676F EB0C                    jmp 0049677D

* Possible StringData Ref from Data Obj ->"demoav2.mad"
                                  |
:00496771 B890CF5300              mov eax, 0053CF90
:00496776 EB05                    jmp 0049677D

* Possible StringData Ref from Data Obj ->"demoav3.mad"
                                  |
:00496778 B89CCF5300              mov eax, 0053CF9C

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:00496768(U), :0049676F(U), :00496776(U)
|
:0049677D E81EFEFFFF              call 004965A0

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0049675A(C)
|
:00496782 B816000000              mov eax, 00000016
:00496787 8B15E82B7000            mov edx, dword ptr [00702BE8]
:0049678D 31DB                    xor ebx, ebx
  -- Continuing program code --

	No problem here, this one is actually kind of easy!  Just kill the conditional jump and no more
title movies or demo movies.  Alright, one down lot's more to go:
	Time to get rid of some of the audio.  The audio that'll have to go is the music at the main menu
and the music that gets played during the actual racing of tracks.  Music files are in ".mus" format and
there just happens to be a data string ref of the same name.  Double click on it and you're here:

* Referenced by a CALL at Addresses:
|:004104BE   , :004104FA   , :0041054B   , :00410597   , :004105E4   
|:0044B5DB   , :0049678F   , :004C42B7                              <-- Called 8 times
|
:004105F0 51                      push ecx
:004105F1 56                      push esi
:004105F2 57                      push edi
:004105F3 55                      push ebp
:004105F4 89E5                    mov ebp, esp
:004105F6 81EC0C020000            sub esp, 0000020C
:004105FC 81ED8A020000            sub ebp, 0000028A
:00410602 898586020000            mov dword ptr [ebp+00000286], eax
:00410608 89957E020000            mov dword ptr [ebp+0000027E], edx
:0041060E C78582020000DC050000    mov dword ptr [ebp+00000282], 000005DC
:00410618 83F863                  cmp eax, 00000063                         <-- My original patch went here
:0041061B 7508                    jne 00410625
:0041061D 31F6                    xor esi, esi
:0041061F 89B586020000            mov dword ptr [ebp+00000286], esi

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0041061B(C)
|
:00410625 30E4                    xor ah, ah
:00410627 BF63000000              mov edi, 00000063


  -- Snip large chunk of code --

:00410823 BA10000000              mov edx, 00000010
:00410828 8D857E010000            lea eax, dword ptr [ebp+0000017E]
:0041082E E8CD080D00              call 004E1100
:00410833 A3507A5700              mov dword ptr [00577A50], eax
:00410838 E80B6E0D00              call 004E7648

* Possible StringData Ref from Data Obj ->".mus"                   <-- Data ref that got us here
                                  |
:0041083D 68A0795300              push 005379A0
:00410842 8D457E                  lea eax, dword ptr [ebp+7E]
:00410845 50                      push eax

* Possible StringData Ref from Data Obj ->"%s%s"
                                  |
:00410846 683C795300              push 0053793C
:0041084B 8D857E010000            lea eax, dword ptr [ebp+0000017E]
  -- More code --

	Once I found the ref in the code I just backed up until I found the beginning of the routine.
Then I needed a way to get to the end doing as little as possible.  So I put a jump in the code at
410618 that jumps down the end of this routine.  Then after talking with shadowRUNNER (of Crackstore,
the best site on the web for game cracks and also the home of all my tutorials.  www.crackstore.com)
I found putting a ret (hex code C3) as the first instruction of this routine is an easy way to kill
all calls to it.  Thanks shadowRUNNER for that tip.
	That's only part of the music routines.  Well also need to search for "tech" that'll lead us
to another routine that either plays techno or rock music.  That routine is coded like this:

* Referenced by a CALL at Addresses:
|:0043842A   , :004A3C81                             <-- Called twice
|
:004108C0 51                      push ecx
:004108C1 56                      push esi
:004108C2 57                      push edi
:004108C3 55                      push ebp
:004108C4 89E5                    mov ebp, esp
:004108C6 81EC08010000            sub esp, 00000108
:004108CC 81ED86010000            sub ebp, 00000186
:004108D2 899582010000            mov dword ptr [ebp+00000182], edx
:004108D8 C7857E010000DC050000    mov dword ptr [ebp+0000017E], 000005DC
:004108E2 83F863                  cmp eax, 00000063
:004108E5 7502                    jne 004108E9
:004108E7 31C0                    xor eax, eax

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004108E5(C)
|
:004108E9 30D2                    xor dl, dl
:004108EB 8B0D542B7000            mov ecx, dword ptr [00702B54]
:004108F1 881550355500            mov byte ptr [00553550], dl
:004108F7 85C9                    test ecx, ecx
:004108F9 0F85C2010000            jne 00410AC1
:004108FF 833D149C550000          cmp dword ptr [00559C14], 00000000
:00410906 0F84B5010000            je 00410AC1
:0041090C 83F80A                  cmp eax, 0000000A
:0041090F 0F8DAC010000            jnl 00410AC1
:00410915 85DB                    test ebx, ebx
:00410917 7410                    je 00410929
:00410919 B601                    mov dh, 01
:0041091B 890D189C5500            mov dword ptr [00559C18], ecx
:00410921 883550355500            mov byte ptr [00553550], dh
:00410927 EB0A                    jmp 00410933

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00410917(C)
|
:00410929 C705189C550001000000    mov dword ptr [00559C18], 00000001

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00410927(U)
|
:00410933 740F                    je 00410944
:00410935 A1B8355500              mov eax, dword ptr [005535B8]
:0041093A 8B0C8568355500          mov ecx, dword ptr [4*eax+00553568]
:00410941 51                      push ecx
:00410942 EB08                    jmp 0041094C

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00410933(C)
|
:00410944 8B348568355500          mov esi, dword ptr [4*eax+00553568]
:0041094B 56                      push esi

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00410942(U)
|
:0041094C 68349A7A00              push 007A9A34

* Possible StringData Ref from Data Obj ->"%s%s"
                                  |
:00410951 683C795300              push 0053793C
:00410956 8D457E                  lea eax, dword ptr [ebp+7E]
:00410959 50                      push eax
:0041095A E871EF0C00              call 004DF8D0
:0041095F 83C410                  add esp, 00000010
:00410962 8A0D9A5E5600            mov cl, byte ptr [00565E9A]
:00410968 F6C110                  test cl, 10
:0041096B 7534                    jne 004109A1
:0041096D F6C120                  test cl, 20
:00410970 752F                    jne 004109A1
:00410972 F6059B5E560001          test byte ptr [00565E9B], 01
:00410979 7526                    jne 004109A1
:0041097B 8B3DE42B7000            mov edi, dword ptr [00702BE4]
:00410981 83FF01                  cmp edi, 00000001
:00410984 7507                    jne 0041098D

* Possible StringData Ref from Data Obj ->"tech"              <-- Ref that got us here
                                  |
:00410986 BE88795300              mov esi, 00537988
:0041098B EB19                    jmp 004109A6

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00410984(C)
|
:0041098D 85FF                    test edi, edi

	Okay, we'll need to take a look at the two callers to the above code and see what they do.
The first routine:

  -- Program code --
:00438426 89F2                    mov edx, esi
:00438428 31DB                    xor ebx, ebx

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0043841F(U)
|
:0043842A E89184FDFF              call 004108C0                <-- Play the music
:0043842F C605FC5B560001          mov byte ptr [00565BFC], 01

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:004383D8(C), :004383FE(C), :00438408(C)
|
:00438436 8B5118                  mov edx, dword ptr [ecx+18]
:00438439 8B4916                  mov ecx, dword ptr [ecx+16]
  -- Continuing program code --

	That's a short little snippet of code.  The call doesn't return any special value so we'll just
kill the call.  Overwrite that call with mov eax, 00000000. Now let's check out the second caller:

  -- Program code --
:004A3C7A 31DB                    xor ebx, ebx

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004A3C76(U)
|
:004A3C7C A1AC447000              mov eax, dword ptr [007044AC]
:004A3C81 E83ACCF6FF              call 004108C0                    <-- Call the music routine
:004A3C86 C605FC5B560001          mov byte ptr [00565BFC], 01
:004A3C8D EB08                    jmp 004A3C97

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004A3C64(C)
|
:004A3C8F 30D2                    xor dl, dl
:004A3C91 8815FC5B5600            mov byte ptr [00565BFC], dl

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004A3C8D(U)
|
:004A3C97 31C0                    xor eax, eax
:004A3C99 E812420400              call 004E7EB0
  -- Continuing program code --

	Again short so the same type of edit will work for this call as well.  Alright, we have gone
through most of the music code but there is one last one to check out.  This time it was found by
click on the "tech.mus"  That'll put you in the middle of this routine:

* Referenced by a CALL at Address:
|:00478371                                            <-- Called once  :-)
|
:00410130 53                      push ebx
:00410131 51                      push ecx
:00410132 52                      push edx
:00410133 56                      push esi
:00410134 57                      push edi
:00410135 55                      push ebp
:00410136 89E5                    mov ebp, esp
:00410138 81EC2C010000            sub esp, 0000012C
:0041013E 81ED82000000            sub ebp, 00000082
:00410144 89C1                    mov ecx, eax
:00410146 BA00000800              mov edx, 00080000
:0041014B 31DB                    xor ebx, ebx
:0041014D 8B3D542B7000            mov edi, dword ptr [00702B54]
:00410153 895D72                  mov dword ptr [ebp+72], ebx
:00410156 895D6E                  mov dword ptr [ebp+6E], ebx
:00410159 895576                  mov dword ptr [ebp+76], edx
:0041015C 85FF                    test edi, edi
:0041015E 0F85B8020000            jne 0041041C
:00410164 83F80A                  cmp eax, 0000000A
:00410167 0F8DAF020000            jnl 0041041C
:0041016D E81E370900              call 004A3890
:00410172 833DF85B560000          cmp dword ptr [00565BF8], 00000000
:00410179 0F859D020000            jne 0041041C
:0041017F BB10000000              mov ebx, 00000010
:00410184 B838795300              mov eax, 00537938
:00410189 E8D2160D00              call 004E1860
:0041018E 8B15E42B7000            mov edx, dword ptr [00702BE4]
:00410194 89457A                  mov dword ptr [ebp+7A], eax
:00410197 83FA03                  cmp edx, 00000003
:0041019A 0F8D92000000            jnl 00410232
:004101A0 8B1C8D68355500          mov ebx, dword ptr [4*ecx+00553568]
:004101A7 53                      push ebx
:004101A8 68349A7A00              push 007A9A34

* Possible StringData Ref from Data Obj ->"%s%s"
                                  |
:004101AD 683C795300              push 0053793C
:004101B2 8D8556FFFFFF            lea eax, dword ptr [ebp+FFFFFF56]
:004101B8 50                      push eax
:004101B9 E812F70C00              call 004DF8D0
:004101BE 8A259A5E5600            mov ah, byte ptr [00565E9A]
:004101C4 83C410                  add esp, 00000010
:004101C7 F6C410                  test ah, 10
:004101CA 7534                    jne 00410200
:004101CC F6C420                  test ah, 20
:004101CF 752F                    jne 00410200
:004101D1 F6059B5E560001          test byte ptr [00565E9B], 01
:004101D8 7526                    jne 00410200
:004101DA 8B35E42B7000            mov esi, dword ptr [00702BE4]
:004101E0 83FE01                  cmp esi, 00000001
:004101E3 7507                    jne 004101EC

* Possible StringData Ref from Data Obj ->"tech.mus"        <-- What got us here
                                  |
:004101E5 BE50795300              mov esi, 00537950
:004101EA EB19                    jmp 00410205

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004101E3(C)
|
:004101EC 85F6                    test esi, esi
:004101EE 7410                    je 00410200

	Again, once I found the ref I just backed up to the start of the routine.  Now we have to
look at who called this routine and what that section of code does:

* Referenced by a CALL at Address:
|:004A396D   
|
:00478360 55                      push ebp
:00478361 89E5                    mov ebp, esp
:00478363 833D542B700000          cmp dword ptr [00702B54], 00000000
:0047836A 7516                    jne 00478382                       <-- Jump for user choosing no music?
:0047836C A1AC447000              mov eax, dword ptr [007044AC]
:00478371 E8BA7DF9FF              call 00410130                      <-- Call the music routine
:00478376 E815B50200              call 004A3890
:0047837B 833DF85B560000          cmp dword ptr [00565BF8], 00000000

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0047836A(C)
|
:00478382 5D                      pop ebp
:00478383 C3                      ret

	Very short routine here as well.  There is the conditional jump at 47836A that I would say is
used when the user selects no music during the races.  But just to make sure we'll kill the call by
overwriting it.  Finally it's time to test the game after you have made these patches:

CD check:
 E8 14 23 01 00 to B8 00 00 00 00  at offset 669,223

Kill intro video and demo videos
Search for: 7D 08 to 90 90 at offset 613,187

Kill music at main menu and during races:
 51 to C3  at offset  63,984
 E8 91 84 FD FF to B8 00 00 00 00 at offset 227,370
 E8 BA 7D F9 FF to B8 00 00 00 00 at offset 489,329
 E8 3A CC F6 FF to B8 00 00 00 00 at offset 667,777

	The game loads in and you can select the race and the car you want.  Then you start the race
and WHAM!!!  NFS3 pops up with a pop-up dialog box and tells you that the "SNDpathcontrol - PATHFINDER NOT
INITIALIZED."  Well, that must come from not loading and playing the music files.  So you'll need to find
the routine that prints that message.  Find the string ref and double click on it to put you here:

* Referenced by a CALL at Addresses:
|:0041363A   , :00418DB6   , :00418E35   , :00418E71   , :00418EB5   <-- Called five times
|
:004E78DC 57                      push edi
:004E78DD 55                      push ebp
:004E78DE 803D94F6A10000          cmp byte ptr [00A1F694], 00
:004E78E5 741C                    je 004E7903                         <-- We want to take this jump
:004E78E7 833DCCF6A10000          cmp dword ptr [00A1F6CC], 00000000
:004E78EE 741B                    je 004E790B
:004E78F0 85C0                    test eax, eax
:004E78F2 7C4C                    jl 004E7940
:004E78F4 83F87F                  cmp eax, 0000007F
:004E78F7 7F47                    jg 004E7940
:004E78F9 A256B95600              mov byte ptr [0056B956], al
:004E78FE 31C0                    xor eax, eax
:004E7900 5D                      pop ebp
:004E7901 5F                      pop edi
:004E7902 C3                      ret

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004E78E5(C)
|
:004E7903 B8F2FFFFFF              mov eax, FFFFFFF2                   <-- Get here to continue
:004E7908 5D                      pop ebp
:004E7909 5F                      pop edi
:004E790A C3                      ret

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004E78EE(C)                                                        <-- Getting here means NFS3 had an error
|
* Possible StringData Ref from Data Obj ->"cmn\spathold.c"
                                  |
:004E790B BF88BA5400              mov edi, 0054BA88

* Possible StringData Ref from Data Obj ->"SNDpathcontrol"
                                  |
:004E7910 BDA4BB5400              mov ebp, 0054BBA4
:004E7915 B83A020000              mov eax, 0000023A

* Possible StringData Ref from Data Obj ->"SNDpathcontrol - PATHFINDER NOT "  <-- Print it
                                        ->"INITIALIZED."
                                  |
:004E791A 68B4BB5400              push 0054BBB4
:004E791F 893D50315500            mov dword ptr [00553150], edi
:004E7925 892D54315500            mov dword ptr [00553154], ebp
:004E792B A358315500              mov dword ptr [00553158], eax
:004E7930 E8DB96F1FF              call 00401010
:004E7935 B8F2FFFFFF              mov eax, FFFFFFF2
:004E793A 83C404                  add esp, 00000004
:004E793D 5D                      pop ebp
:004E793E 5F                      pop edi
:004E793F C3                      ret

	Just find the conditional jump at 4E78E5 in the exe and change it to a non conditional jump
Rerun the game and WHAM!! "SNDpathevent - PATHFINDER NOT INITIALIZED." error.  Do the same as above,
find the string ref and double click on it and here you are:

* Referenced by a CALL at Addresses:
|:00413684   , :004137BC   , :00418D37   , :00418DAC   , :00418E2E   
|:00418F1C   , :00418FB3                                             <-- Called 7 times for this one
|
:004E797C 51                      push ecx
:004E797D 56                      push esi
:004E797E 55                      push ebp
:004E797F 803D94F6A10000          cmp byte ptr [00A1F694], 00
:004E7986 744E                    je 004E79D6                        <-- Take this jump to continue
:004E7988 833DCCF6A10000          cmp dword ptr [00A1F6CC], 00000000
:004E798F 744E                    je 004E79DF
:004E7991 85C0                    test eax, eax
:004E7993 0F8C7C000000            jl 004E7A15
:004E7999 8B0DECB95600            mov ecx, dword ptr [0056B9EC]
:004E799F 8A4907                  mov cl, byte ptr [ecx+07]
:004E79A2 81E1FF000000            and ecx, 000000FF
:004E79A8 39C8                    cmp eax, ecx
:004E79AA 7D69                    jge 004E7A15
:004E79AC 83FA01                  cmp edx, 00000001
:004E79AF 0F849B000000            je 004E7A50
:004E79B5 66833DE6B9560001        cmp word ptr [0056B9E6], 0001
:004E79BD 0F85B2000000            jne 004E7A75
:004E79C3 66A3E8B95600            mov word ptr [0056B9E8], ax
:004E79C9 668915EAB95600          mov word ptr [0056B9EA], dx
:004E79D0 31C0                    xor eax, eax
:004E79D2 5D                      pop ebp
:004E79D3 5E                      pop esi
:004E79D4 59                      pop ecx
:004E79D5 C3                      ret

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004E7986(C)
|
:004E79D6 B8F2FFFFFF              mov eax, FFFFFFF2               <-- Getting here continues with the game
:004E79DB 5D                      pop ebp
:004E79DC 5E                      pop esi
:004E79DD 59                      pop ecx
:004E79DE C3                      ret

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004E798F(C)                                                        <-- Getting here means NFS3 had an error
|
* Possible StringData Ref from Data Obj ->"cmn\spathold.c"
                                  |
:004E79DF BD88BA5400              mov ebp, 0054BA88

* Possible StringData Ref from Data Obj ->"SNDpathevent"
                                  |
:004E79E4 B818BC5400              mov eax, 0054BC18
:004E79E9 BAD0020000              mov edx, 000002D0

* Possible StringData Ref from Data Obj ->"SNDpathevent - PATHFINDER NOT "  <-- Print it!
                                        ->"INITIALIZED."
                                  |
:004E79EE 6828BC5400              push 0054BC28
:004E79F3 892D50315500            mov dword ptr [00553150], ebp
:004E79F9 A354315500              mov dword ptr [00553154], eax
:004E79FE 891558315500            mov dword ptr [00553158], edx
:004E7A04 E80796F1FF              call 00401010
:004E7A09 B8F2FFFFFF              mov eax, FFFFFFF2
:004E7A0E 83C404                  add esp, 00000004
:004E7A11 5D                      pop ebp
:004E7A12 5E                      pop esi
:004E7A13 59                      pop ecx
:004E7A14 C3                      ret

	Again, just find the conditional jump at 4E7986 in the exe and change it to a non conditional
jump just like we did with the first error.  Alright, rerun the game and WHAM!! "SNDpatheventinterrupt
- PATHFINDER NOT INITIALIZED." error.  Jeezzzz  How many times is this going to happen?  Here we go again,
the same thing as above.  Find the string ref and double click on it to get to this new routine:

* Referenced by a CALL at Addresses:
|:00413664   , :00418F93                        <-- Only called twice
|
:004E7A88 53                      push ebx
:004E7A89 51                      push ecx
:004E7A8A 52                      push edx
:004E7A8B 55                      push ebp
:004E7A8C 89C2                    mov edx, eax
:004E7A8E 803D94F6A10000          cmp byte ptr [00A1F694], 00
:004E7A95 0F84E0000000            je 004E7B7B                           <-- Take this jump to continue
:004E7A9B 833DCCF6A10000          cmp dword ptr [00A1F6CC], 00000000
:004E7AA2 0F84DD000000            je 004E7B85
:004E7AA8 85D2                    test edx, edx
:004E7AAA 0F8C0C010000            jl 004E7BBC
:004E7AB0 A1ECB95600              mov eax, dword ptr [0056B9EC]
:004E7AB5 8A4007                  mov al, byte ptr [eax+07]
:004E7AB8 25FF000000              and eax, 000000FF
:004E7ABD 39C2                    cmp edx, eax
:004E7ABF 0F8DF7000000            jnl 004E7BBC
:004E7AC5 E86A970100              call 00501234
:004E7ACA 0FBF0554B95600          movsx eax, word ptr [0056B954]
:004E7AD1 C1E002                  shl eax, 02
:004E7AD4 89C1                    mov ecx, eax
:004E7AD6 C1E003                  shl eax, 03
:004E7AD9 29C8                    sub eax, ecx
:004E7ADB 8B0DF0B95600            mov ecx, dword ptr [0056B9F0]
:004E7AE1 01C8                    add eax, ecx
:004E7AE3 31C9                    xor ecx, ecx
:004E7AE5 8A08                    mov cl, byte ptr [eax]
:004E7AE7 A1ECB95600              mov eax, dword ptr [0056B9EC]
:004E7AEC 8A4007                  mov al, byte ptr [eax+07]
:004E7AEF 25FF000000              and eax, 000000FF
:004E7AF4 0FAFC1                  imul eax, ecx
:004E7AF7 01D0                    add eax, edx
:004E7AF9 8B155CB95600            mov edx, dword ptr [0056B95C]
:004E7AFF 31DB                    xor ebx, ebx
:004E7B01 8A1C02                  mov bl, byte ptr [edx+eax]
:004E7B04 8D049D00000000          lea eax, dword ptr [4*ebx+00000000]
:004E7B0B 8B1560B95600            mov edx, dword ptr [0056B960]
:004E7B11 B904000000              mov ecx, 00000004
:004E7B16 01D0                    add eax, edx
:004E7B18 8B00                    mov eax, dword ptr [eax]
:004E7B1A 0FC8                    bswap eax
:004E7B1C F7D9                    neg ecx
:004E7B1E 8D0CCD20000000          lea ecx, dword ptr [8*ecx+00000020]
:004E7B25 D3E8                    shr eax, cl
:004E7B27 89C2                    mov edx, eax
:004E7B29 B864B95600              mov eax, 0056B964
:004E7B2E E861070000              call 004E8294
:004E7B33 85C0                    test eax, eax
:004E7B35 0F85BD000000            jne 004E7BF8
:004E7B3B E860100000              call 004E8BA0
:004E7B40 A358B95600              mov dword ptr [0056B958], eax
:004E7B45 66891D54B95600          mov word ptr [0056B954], bx
:004E7B4C BAFFFFFFFF              mov edx, FFFFFFFF
:004E7B51 668915E4B95600          mov word ptr [0056B9E4], dx
:004E7B58 31DB                    xor ebx, ebx
:004E7B5A 66891DE6B95600          mov word ptr [0056B9E6], bx
:004E7B61 668915E8B95600          mov word ptr [0056B9E8], dx
:004E7B68 66891DEAB95600          mov word ptr [0056B9EA], bx
:004E7B6F E81C970100              call 00501290
:004E7B74 31C0                    xor eax, eax
:004E7B76 5D                      pop ebp
:004E7B77 5A                      pop edx
:004E7B78 59                      pop ecx
:004E7B79 5B                      pop ebx
:004E7B7A C3                      ret

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004E7A95(C)
|
:004E7B7B B8F2FFFFFF              mov eax, FFFFFFF2            <-- Get here to continue
:004E7B80 5D                      pop ebp
:004E7B81 5A                      pop edx
:004E7B82 59                      pop ecx
:004E7B83 5B                      pop ebx
:004E7B84 C3                      ret

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004E7AA2(C)
|
* Possible StringData Ref from Data Obj ->"cmn\spathold.c"     <-- Getting here means NFS3 had an error (again!)
                                  |
:004E7B85 BD88BA5400              mov ebp, 0054BA88

* Possible StringData Ref from Data Obj ->"SNDpatheventinterrupt"
                                  |
:004E7B8A B878BC5400              mov eax, 0054BC78
:004E7B8F BA03030000              mov edx, 00000303

* Possible StringData Ref from Data Obj ->"SNDpatheventinterrupt - PATHFINDER "  <-- Print it
                                        ->"NOT INITIALIZED."
                                  |
:004E7B94 6890BC5400              push 0054BC90
:004E7B99 892D50315500            mov dword ptr [00553150], ebp
:004E7B9F A354315500              mov dword ptr [00553154], eax
:004E7BA4 891558315500            mov dword ptr [00553158], edx
:004E7BAA E86194F1FF              call 00401010
:004E7BAF B8F2FFFFFF              mov eax, FFFFFFF2
:004E7BB4 83C404                  add esp, 00000004
:004E7BB7 5D                      pop ebp
:004E7BB8 5A                      pop edx
:004E7BB9 59                      pop ecx
:004E7BBA 5B                      pop ebx
:004E7BBB C3                      ret

	Alright, last time... if this doesn't work then we're going down the wrong trail with this.  Find
the conditional jump in the exe and change it to a NOP and a non conditional jump.  Now finally run Need
For Speed 3: Hot Pursuit!!  Now you can play the game all the way through without any errors or crashes
and more importantly, without the CD.  What you have left is known as a CD rip.  That is you've ripped
out the need for anything that was left on the CD, usually music and movies.  Anyways, once you have made
all the patches you have finally crack NFS3.  It took a lot of work, but it's worth it for this one!

  In step by step fasion:

1.  Do a max install and then apply these edits:
2.  Make the following edits by version:

For the US CD version edit nfs3.exe
=============================================
CD check:
Search for: E8 B4 25 01 00  at offset 668,007
Change to : 90 90 90 90 90

Kill intro video and demo videos
Search for: 7D 08 31 C0 5D  at offset 611,971
Change to : 90 90 -- -- --

Kill music at main menu and during races:
Search for: 51 56 57 55 89  at offset  63,728
Change to : C3 -- -- -- --

Search for: E8 91 86 FD FF  at offset 226,602
Change to : 90 90 90 90 90

Search for: E8 4A 80 F9 FF  at offset 488,417
Change to : 90 90 90 90 90

Search for: E8 FA CF F6 FF  at offset 666,561
Chagne to : 90 90 90 90 90

Ingnore sound errors due to no music
Search for: 74 1C 83 3D 2C  at offset 943,205
Chagne to : EB -- -- -- --

Search for: 74 4E 83 3D 2C  at offset 943,366
Change to : EB -- -- -- --

Search for: 0F 84 E0 00 00  at offset 943,637
Change to : 90 E9 -- -- --


For "Network Play System" patch1 edit nfs3.exe
=============================================
CD check:
Search for: E8 14 23 01 00  at offset 669,223
Change to : B8 00 00 00 00

Kill intro video and demo videos
Search for: 7D 08 31 C0 5D  at offset 613,187
Change to : 90 90 -- -- --

Kill music at main menu and during races:
Search for: 51 56 57 55 89  at offset  63,984
Change to : C3 -- -- -- --

Search for: E8 91 84 FD FF  at offset 227,370
Change to : B8 00 00 00 00

Search for: E8 BA 7D F9 FF  at offset 489,329
Change to : B8 00 00 00 00

Search for: E8 3A CC F6 FF  at offset 667,777
Chagne to : B8 00 00 00 00

Ingnore sound errors due to no music
Search for: 74 1C 83 3D 2C  at offset 945,381
Chagne to : EB -- -- -- --

Search for: 74 4E 83 3D 2C  at offset 945,542
Change to : EB -- -- -- --

Search for: 0F 84 E0 00 00  at offset 945,813
Change to : 90 E9 -- -- --


For "Network Play System" patch2 edit nfs3.exe
=============================================
CD check:
Search for: E8 14 23 01 00  at offset 669,207
Change to : B8 00 00 00 00

Kill intro video and demo videos
Search for: 7D 08 31 C0 5D  at offset 613,171
Change to : 90 90 -- -- --

Kill music at main menu and during races:
Search for: 51 56 57 55 89  at offset  63,984
Change to : C3 -- -- -- --

Search for: E8 A1 84 FD FF  at offset 227,354
Change to : B8 00 00 00 00

Search for: E8 CA 7D F9 FF  at offset 489,313
Change to : B8 00 00 00 00

Search for: E8 4A CC F6 FF  at offset 667,761
Chagne to : B8 00 00 00 00

Ingnore sound errors due to no music
Search for: 74 1C 83 3D CC  at offset 945,365
Chagne to : EB -- -- -- --

Search for: 74 4E 83 3D CC  at offset 945,526
Change to : EB -- -- -- --

Search for: 0F 84 E0 00 00  at offset 945,797
Change to : 90 E9 -- -- --

	Quite a bit of  work for this one, but after a max install and these patches you can play the game
without the CD being on line.  Of course you loose the movies and music this way, but it's cracked.

Static Vengeance

NOTE: Thanks again to shadowRUNNER for the "better" kill music 51 -> C3 edit!
